home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DDJMAG / DDJ8801.ZIP / NARO.ZIP / OUTHEX.C < prev    next >
Text File  |  1987-10-30  |  5KB  |  238 lines

  1. /*
  2.     Copyright (C) 1987 Paradigm Systems Inc.  All rights reserved.
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <io.h>
  8. #include <string.h>
  9. #include <malloc.h>
  10. #include <dos.h>
  11.  
  12. #include "loc.h"
  13. #include "externs.h"
  14.  
  15.  
  16. void    output_hex_OMF(hex_file, seg_list, entry_point)
  17. int    hex_file ;
  18. SEG_DESCRIPTOR    *seg_list ;
  19. unsigned char    *entry_point ;
  20. {
  21.     unsigned int    offset, i, count ;
  22.     unsigned char    *seg_start, *text ;
  23.  
  24.     SEG_DESCRIPTOR    *p ;
  25.  
  26.     /*
  27.         This function controls the sequencing of the Intel extended hex
  28.         output using the Intel hex output routines.
  29.     */
  30.  
  31.     /* Run through the segment list and output all ROMable segments */
  32.     p = seg_list ;
  33.     while (p != NULL)   {
  34.         if (p->romable == TRUE)   {
  35.  
  36.             /* Allocate enough memory to hold the segment (up to 64K) */
  37.             if ((text = get_mem((unsigned long) p->len)) == NULL)   {
  38.                 perror(__FILE__) ;
  39.                 exit(1) ;
  40.             }
  41.  
  42.             /* Locate the position of the segment in the load module file */
  43.             if (lseek(tmp_file, p->position, SEEK_SET) == -1L)   {
  44.                 perror(__FILE__) ;
  45.                 exit(1) ;
  46.             }
  47.  
  48.             /* Read in the segment and pad with zero if necessary */
  49.             count = read(tmp_file, text, p->len) ;
  50.             if (count != p->len)   {
  51.                 if (count == -1)   {
  52.                     perror(__FILE__) ;
  53.                     exit(1) ;
  54.                 }
  55.                 else
  56.                     memset(text + count, '\0', p->len - count) ;
  57.             }
  58.  
  59.             /* Write the segment number out in an address record */
  60.             write_ADDR_record(hex_file, p->pseg) ;
  61.  
  62.             /* Output the segment as a series of 16 byte data records */
  63.             offset = p->offset ;
  64.             seg_start = text ;
  65.             for (i = 0; i < p->len / 16; i++)   {
  66.                 write_DATA_record(hex_file, offset, seg_start, 16) ;
  67.                 offset += 16 ;
  68.                 seg_start += 16 ;
  69.             }
  70.  
  71.             /* Handle any remaining data */
  72.             if ((p->len % 16) != 0)
  73.                 write_DATA_record(hex_file, offset, seg_start, p->len % 16) ;
  74.  
  75.             free_mem(text) ;
  76.         }
  77.         p = p->next ;
  78.     }
  79.  
  80.     /* Write the START and EOF records */
  81.     write_START_record(hex_file, entry_point) ;
  82.     write_EOF_record(hex_file) ;
  83.  
  84.     return ;
  85. }
  86.  
  87.  
  88. void    write_ADDR_record(file, usba)
  89. int    file ;
  90. unsigned int    usba ;
  91. {
  92.     unsigned char    buf[16], *p ;
  93.     unsigned char    len_field = 2 ;
  94.  
  95.     /*
  96.         This function writes an Intel extended hex Address record to the
  97.         output file.  Inputs are the file handle and the USBA (segment
  98.         base address).
  99.     */
  100.  
  101.     p = buf ;
  102.     *p++ = high_byte(usba) ;
  103.     *p++ = low_byte(usba) ;
  104.  
  105.     output_hex_record(file, ADDR_RECORD, 0, buf, p - buf) ;
  106.  
  107.     return ;
  108. }
  109.  
  110.  
  111. void    write_EOF_record(file)
  112. int    file ;
  113. {
  114.     /*
  115.         This function writes an Intel extended hex EOF record to the
  116.         output file.
  117.     */
  118.         
  119.     output_hex_record(file, EOF_RECORD, 0, NULL, 0) ;
  120.     return ;
  121. }
  122.  
  123.  
  124. void    write_DATA_record(file, offset, text, len)
  125. int    file ;
  126. unsigned int    offset ;
  127. unsigned char    *text ;
  128. unsigned int    len ;
  129. {
  130.  
  131.     /*
  132.         This function writes an Intel extended hex Data record to the
  133.         specified output file.
  134.     */
  135.  
  136.     output_hex_record(file, DATA_RECORD, offset, text, len) ;
  137.  
  138.     return ;
  139. }
  140.  
  141.  
  142. void    write_START_record(file, entry)
  143. int    file ;
  144. unsigned char    *entry ;
  145. {
  146.     unsigned char    *buf, *p ;
  147.     unsigned int    count ;
  148.  
  149.     unsigned char    len_field = 4;
  150.     unsigned int    addr_field = 0 ;
  151.     unsigned char    rec_type = START_RECORD ;
  152.  
  153.     /*
  154.         This function writes an Intel extended hex Start record to the
  155.         output file.
  156.     */
  157.  
  158.     /* Allocate some memory to build the data field in */
  159.     if ((p = buf = (unsigned char *) malloc(32)) == NULL)   {
  160.         perror(__FILE__) ;
  161.         exit(1) ;
  162.     }
  163.  
  164.     /* Store the start address in the data field (segment first) */
  165.     *p++ = high_byte(FP_SEG(entry)) ;
  166.     *p++ = low_byte(FP_SEG(entry)) ;
  167.  
  168.     /* And then the offset */
  169.     *p++ = high_byte(FP_OFF(entry)) ;
  170.     *p++ = low_byte(FP_OFF(entry)) ;
  171.  
  172.     /* Output the record */
  173.     output_hex_record(file, START_RECORD, 0, buf, p - buf) ;
  174.  
  175.     free(buf) ;
  176.     return ;
  177. }
  178.  
  179.  
  180. void    output_hex_record(file, type, addr, data, length)
  181. int    file ;
  182. unsigned char    type ;
  183. unsigned int    addr ;
  184. unsigned char    *data ;
  185. unsigned char    length ;
  186. {
  187.     char    *p, *buf ;
  188.     unsigned int    size, count ;
  189.     unsigned char    chksum, digit ;
  190.  
  191.     /*
  192.         This function does all of the work of writing an Intel extended
  193.         hex output record.  The inputs to this routine are:
  194.             file        output file handle
  195.             type        record type
  196.             addr        address field value
  197.             data        data field contents
  198.             length    size of the data field
  199.     */
  200.  
  201.     /* Allocate some memory to build the output record in */
  202.     if ((p = buf = malloc(550)) == NULL)   {
  203.         perror(__FILE__);
  204.         exit(1) ;
  205.     }
  206.  
  207.     /* Build the prefix for the data field */
  208.     p += sprintf(p, ":%02X%02X%02X%02X", length, high_byte(addr), \
  209.         low_byte(addr), type) ;
  210.  
  211.     /* Compute the checksum on the prefix */
  212.     chksum = length + high_byte(addr) + low_byte(addr) + type ;
  213.  
  214.     /*    Build the data field byte by byte */
  215.     while (length--)   {
  216.         digit = (*data >> 4) & 0x0f ;
  217.         *p++ = (digit > 9) ? digit + 0x37 : digit + '0' ;
  218.         digit = *data & 0x0f ;
  219.         *p++ = (digit > 9) ? digit + 0x37 : digit + '0' ;
  220.         chksum += *data++ ;
  221.     }
  222.  
  223.     /* Compute the complement of the checksum and output */
  224.     chksum = ~chksum + 1 ;
  225.     p += sprintf(p, "%02X\r\n",chksum) ;
  226.  
  227.     /* Compute the size of the output record and output */
  228.     size = p - buf ;
  229.     count = write(file, buf, size) ;
  230.     if (count != size)   {
  231.         perror(__FILE__) ;
  232.         exit(1) ;
  233.     }
  234.  
  235.     free(buf) ;
  236.     return ;
  237. }
  238.